﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Mail;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Collections;
using EmailClient.DTO;
using EmailClient.DAO;
using System.Web;
using System.Reflection;

namespace EmailClient
{
    public partial class NewEmail : DevExpress.XtraBars.Ribbon.RibbonForm
    {
        private List<string> ListAccount
        {
            get;
            set;
        }

        ArrayList attachments = new ArrayList();
        public NewEmail()
        {
            InitializeComponent();
        }
        public static bool CheckEmail(string emailAddress)
        {
            string patternStrict = @"^(([^<>()[\]\\.,;:\s@\""]+"
                + @"(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))@"
                + @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
                + @"\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+"
                + @"[a-zA-Z]{2,}))$";
            Regex reStrict = new Regex(patternStrict);
            bool isStrictMatch = false;
            if (emailAddress.Contains(";"))
            {
                string[] listEmails = emailAddress.Split(";".ToCharArray());
                for (int i = 0; i < listEmails.Length; i++)
                {
                    if (!reStrict.IsMatch(listEmails[i]))
                    {
                        isStrictMatch = false;
                        break;
                    }
                    else
                        isStrictMatch = true;
                }
            }
            else
                isStrictMatch = reStrict.IsMatch(emailAddress);
            return isStrictMatch;
        }

        //this method will get email you want to receive
        public void GetTo(MailMessage mail, string to)
        {
            if (CheckEmail(to))
            {
                if (to.Contains(";"))
                {
                    //get list email
                    string[] _EmailsTO = to.Split(",".ToCharArray());
                    for (int i = 0; i < _EmailsTO.Length; i++)
                    {
                        mail.To.Add(new MailAddress(_EmailsTO[i]));
                    }
                }
                else
                {
                    //get 1 email
                    mail.To.Add(new MailAddress(to));
                }
            }
        }
        //this method will get CC you want to receive
        public void GetCC(MailMessage mail, string cc)
        {
            if (CheckEmail(cc))
            {
                if (cc.Contains(";"))
                {
                    //get list CC
                    string[] _EmailsCC = cc.Split(",".ToCharArray());
                    for (int i = 0; i < _EmailsCC.Length; i++)
                    {
                        mail.CC.Add(new MailAddress(_EmailsCC[i]));
                    }
                }
                else
                {
                    //get 1 CC
                    mail.CC.Add(new MailAddress(cc));
                }
            }
        }

        //this method will get Bcc you want to receive
        public void GetBcc(MailMessage mail, string bcc)
        {
            if (CheckEmail(bcc))
            {
                if (bcc.Contains(";"))
                {
                    //get list Bcc
                    string[] _EmailsBcc = bcc.Split(",".ToCharArray());
                    for (int i = 0; i < _EmailsBcc.Length; i++)
                    {
                        mail.Bcc.Add(new MailAddress(_EmailsBcc[i]));
                    }
                }
                else
                {
                    //get 1 Bcc
                    mail.Bcc.Add(new MailAddress(bcc));
                }
            }
        }

        //this method will get subject of email you want to receive
        public void GetSubject(MailMessage mail, string subject)
        {
            mail.Subject = subject;
        }

        //this method will get body of email you want to receive
        public void GetBody(MailMessage mail, string body)
        {
            mail.IsBodyHtml = true;
            mail.Body = body;
        }

        //main method to send email
        public void SendEmail(MailMessage mail, string from, string password, string host, int port)
        {
            //Setup SMTP setting
            SmtpClient smtp = new SmtpClient();
            smtp.Host = host;
            smtp.Port = port;
            System.Net.NetworkCredential networkCredential = new System.Net.NetworkCredential(from, password);

            //Send email
            smtp.EnableSsl = true;
            smtp.UseDefaultCredentials = false;
            smtp.Credentials = networkCredential;
            smtp.Send(mail);

            //Save email
            smtp.EnableSsl = false;
            smtp.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
            string path = Application.StartupPath + @"\EmailDB\" + from + @"\Sent Items\";
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            smtp.PickupDirectoryLocation = path;
            smtp.Send(mail);
        }

        //Send mail
        private void simpleButton_Send_Click(object sender, EventArgs e)
        {
            using (MailMessage mail = new MailMessage())
            {
                //get email of sender
                string from = cb_From.Text;
                string emailName = cb_From.Text;
                DataTable dt = AccountDAO.GetAccountByAccountAddress(emailName);
                //initialize From for object email
                mail.From = new MailAddress(from);
                string password = dt.Rows[0]["Password"].ToString();
                string host = dt.Rows[0]["SmtpHost"].ToString();
                int port = Int32.Parse(dt.Rows[0]["SmtpPort"].ToString());
                if (txt_To.Text.Trim().Equals(string.Empty) || txt_To.Text.Trim().Equals("To"))
                    //show error when txtTo is null
                    MessageBox.Show("Your email receive is null!!");
                else
                {
                    string to = txt_To.Text.Trim();
                    if (!CheckEmail(to))
                    {
                        //show message when email receive isn't exist
                        MessageBox.Show("Your email receive isn't exist!!");
                    }
                    else
                    {
                        //initialize To for object email
                        GetTo(mail, to);
                        if (!txt_CC.Text.Trim().Equals(string.Empty))
                            //initialize CC for object email
                            GetCC(mail, txt_CC.Text.Trim());
                        if (!txt_Bcc.Text.Trim().Equals(string.Empty))
                            //initialize Bcc for object emai
                            GetBcc(mail, txt_Bcc.Text.Trim());
                        if (!txt_Subject.Text.Trim().Equals(string.Empty))
                            //initialize Subject for object email
                            GetSubject(mail, txt_Subject.Text.Trim());
                        if (!richEditControl_Body.Text.Trim().Equals(string.Empty))
                            //initialize Body for object email
                            GetBody(mail, (richEditControl_Body.HtmlText));
                        
                        //{
                        //    POP.Mime.Decode.Rtf2Html rtf = new POP.Mime.Decode.Rtf2Html();
                        //    string body = rtf.ConvertRtfToHtml(richTextBox1);
                        //    GetBody(mail, body.Trim());
                        //}
                        //initialize Attachments for object email
                        GetAttachments(mail);
                        if ((!txt_CC.Text.Trim().Equals(string.Empty) && !txt_CC.Text.Trim().Equals("CC") && !CheckEmail(txt_CC.Text.Trim())) ||
                           (!txt_Bcc.Text.Trim().Equals(string.Empty) && !txt_Bcc.Text.Trim().Equals("Bcc") && !CheckEmail(txt_Bcc.Text.Trim())))
                        {
                            MessageBox.Show("Your email CC or Bcc isn't exist!!");
                        }
                        else
                        {
                            //call method send email
                            try
                            {
                                mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess | DeliveryNotificationOptions.OnFailure |
                                    DeliveryNotificationOptions.Delay;
                                SendEmail(mail, from, password, host, port);
                                MessageBox.Show("Your email has been sent!");
                            }
                            catch
                            {
                                MessageBox.Show("Can't send email");
                            }
                        }
                    }
                }
            }
        }

        public void GetAttachments(MailMessage mail)
        {
            if (List_Attachments.Items.Count > 0)
                foreach (ListViewItem item in List_Attachments.Items)
                {
                    System.Net.Mail.Attachment att = new System.Net.Mail.Attachment(item.Tag.ToString());
                    mail.Attachments.Add(att);
                }
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            openFileDialog1.Reset();
        }

        private void barButtonItem_AttachFile_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                foreach (string filename in openFileDialog1.FileNames)
                {
                    ListViewItem item = new ListViewItem(Path.GetFileName(filename) + " (" + ((double)(new FileInfo(filename).Length / 1000)).ToString("f2") + " KB)");
                    item.ImageIndex = 0;
                    item.Tag = filename;
                    List_Attachments.Items.Add(item);
                }
            }
        }

        private void clearFormattingItem2_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {

        }

        private void List_Attachments_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
                foreach (ListViewItem item in List_Attachments.Items)
                    if (item.Bounds.Contains(e.X, e.Y))
                        popup_AttachFile.Show(Cursor.Position);
        }

        private void toolStripMenuItemRemove_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in List_Attachments.Items)
                if (item.Selected)
                {
                    item.Remove();
                }
        }

        private void toolStripMenuItemOpen_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in List_Attachments.Items)
                if (item.Selected)
                    Process.Start(item.Tag.ToString());
        }

        private void List_Attachments_DoubleClick(object sender, EventArgs e)
        {
            foreach (ListViewItem item in List_Attachments.Items)
                if (item.Selected)
                    Process.Start(item.Tag.ToString());
        }

        private void NewEmail_Load(object sender, EventArgs e)
        {
            cb_From.DataSource = AccountDAO.GetAllAccount();
            cb_From.DisplayMember = cb_From.ValueMember = "EmailAddress";
            ToolTip tooltip1 = new ToolTip();
            tooltip1.SetToolTip(txt_To, "Using ',' to add multi-email");
            ToolTip tooltip2 = new ToolTip();
            tooltip1.SetToolTip(txt_CC, "Using ',' to add multi-email");
            ToolTip tooltip3 = new ToolTip();
            tooltip1.SetToolTip(txt_Bcc, "Using ',' to add multi-email");
        }

        private void barButtonItem2_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            openFileDialog1.ShowDialog();
            foreach (string filename in openFileDialog1.FileNames)
            {
                ListViewItem item = new ListViewItem(Path.GetFileName(filename) + " (" + ((double)(new FileInfo(filename).Length / 1000)).ToString("f2") + " KB)");
                item.ImageIndex = 0;
                item.Tag = filename;
                List_Attachments.Items.Add(item);
            }
        }

        private void simpleButton3_Click(object sender, EventArgs e)
        {
            txt_CC.Visible = true;
        }

        private void simpleButton4_Click(object sender, EventArgs e)
        {
            txt_Bcc.Visible = true;
        }

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            string s = richEditControl_Body.HtmlText;
            MessageBox.Show(s);
        }
        public string parsetext(string text, bool allow)
        {
            //Create a StringBuilder object from the string input
            //parameter
            StringBuilder sb = new StringBuilder(text);
            //Replace all double white spaces with a single white space
            //and &nbsp;
            sb.Replace("  ", " &nbsp;");
            //Check if HTML tags are not allowed
            if (!allow)
            {
                //Convert the brackets into HTML equivalents
                sb.Replace("<", "&lt;");
                sb.Replace(">", "&gt;");
                //Convert the double quote
                sb.Replace("\"", "&quot;");
            }
            //Create a StringReader from the processed string of
            //the StringBuilder
            StringReader sr = new StringReader(sb.ToString());
            StringWriter sw = new StringWriter();
            //Loop while next character exists
            while (sr.Peek() > -1)
            {
                //Read a line from the string and store it to a temp
                //variable
                string temp = sr.ReadLine();
                //write the string with the HTML break tag
                //Note here write method writes to a Internal StringBuilder
                //object created automatically
                sw.Write(temp + "<br>");
            }
            //Return the final processed text
            return sw.GetStringBuilder().ToString();
        }
    }
}
